-- [AuXnet] v2
-- networking framework
-- client side
-- net.connect(address,port) -- connect to a server, returns whether successful
-- net.process() -- run server networking code , should be used very frequently
-- net.set(name,value) -- set a value in the client datastream, and request an update from the server [ ! cvars must be accessed by their CVAR name, not their variable name! ]
-- net.get(name) -- retrieve a value from the server datastream as of the last time net.process() was run
-- net.pushstream(stream) -- encode and broadcast a datastream
-- net.loadstream(stream) -- decode a datastream
-- net.call(event) -- trigger an event on the server
-- net.raw(callback) -- add a function to be called whenever the server receives a message. hands paramaters: ( data: string that was received )
-- net.sraw(data) -- send raw data to the connected server
socket=require "socket"
host=nil
net={ }
stream= { }
cstream= { }
events={ }
actions={ }
lostconnect=function(err) return end
raw=nil
update=nil
function net.process()
	-- synchronize datastream with server, server priority
	if host then
		repeat
			msg,err=host:receive('*l')
			if msg then
				if raw then raw(ms) end
				if msg:sub(1,1)~=":" then
					if msg:sub(1,1)=="<" then
						--print("received server stream - "..msg)
						msg=msg:sub(2)
						repeat
							str,match=msg:match("^([%w%s_]+)=([%w_%!%@%#%$%%%^%&%*%s]+);")
							--print (str,match)
							stream[str]=match
							msg=msg:gsub(str.."="..match..";","")
						until msg==""
					end
					if msg:sub(1,1)=="-" then
						if actions[msg:match("%-(%w+)%-")] then
							actions[msg:match("%-(%w+)%-")](msg:match("^%-%a+%-(.*)"))
						end
					end
				else
					e=msg:sub(2)
					if events[e] then
						events[e]()
					else
						return nil
					end
				end
			end
		until not msg
		if err then
			if err~="timeout" then
				lostconnect(err)
			end
		end
	else
		lostconnect("could not start connection")
		return nil 
	end
	return true
end
function net.action(name,param)
	if not param then error("no parameter given!") end
	if type(param)== "function" then
		actions[name]=param
	else
		if not host then return end
		host:send("-"..name.."-"..param.."\n")
	end
end
function net.pushstream(data)
	packed=""
	for k,v in pairs(data) do
		packed=packed..k.."="..v..";"
	end
	--print(packed)
	if not host then return end
	m,err=host:send(string.format("<%s",packed).."\n")
	--if err then print(err) end
end
function net.connect(addr,port)
	host=socket.connect(addr,port)
	if host then
		host:settimeout(0)
	end
	if not host then return false else return true end
end
function net.get(name)
	return stream[name]
end
function net.close()
	if host then
	host:close()
	end
end
function net.sraw(value)
	host:send(value.."\n")
end
function net.lostconnect(callback)
	lostconnect=callback
end
function net.raw(callback)
	raw=callback
end
function net.set(name,value)
	cstream[name]=value
	net.pushstream(cstream)
	return true
end
function net.call(name)
	if not host then return end
	m,err=host:send(string.format(":%s",name).."\n")
	--if err then print(err) end
end
function net.event(name,callback)
	events[name]=callback
	return true
end